package io.gitee.mingbaobaba.security.core.domain;

import io.gitee.mingbaobaba.security.core.constants.ErrorCodeConstant;
import io.gitee.mingbaobaba.security.core.exception.SecurityBusinessException;
import io.gitee.mingbaobaba.security.core.factory.SecurityFactory;
import io.gitee.mingbaobaba.security.core.utils.JsonUtil;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>SecurityToken</p>
 *
 * @author yingsheng.ye
 * @version 1.0.0
 * @since 2023/8/28 22:25
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class SecurityToken implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * token
     */
    private String token;

    /**
     * 登录Id
     */
    private String loginId;

    /**
     * 设备类型
     */
    private String deviceType;

    /**
     * 过期时间 单位秒
     */
    private Long timeout;

    /**
     * 活跃时间 格式 yyyy-MM-dd HH:mm:ss
     */
    private String activityTime;

    /**
     * 活跃超时时间 单位秒
     */
    private Long activityTimeout;

    /**
     * 状态标记 1 正常 2被踢下线 3被顶下线 4封禁
     */
    private String state;

    /**
     * 创建时间 格式 yyyy-MM-dd HH:mm:ss
     */
    private String createTime;

    /**
     * 更新时间 格式 yyyy-MM-dd HH:mm:ss
     */
    private String updateTime;

    /**
     * token挂载数据
     */
    private final Map<String, Object> tokenMountData = new HashMap<>();

    /**
     * 设置存储信息
     *
     * @param key   key值
     * @param value value值
     * @return SecuritySession
     */
    public SecurityToken setAttribute(String key, Object value) {
        tokenMountData.put(key, value);
        flushTokenStorage();
        return this;
    }

    /**
     * 获取存储信息
     *
     * @param key key值
     * @return Object
     */
    public Object getAttribute(String key) {
        return tokenMountData.get(key);
    }

    /**
     * 获取存储信息
     *
     * @param key    字符串key
     * @param tClass 类型
     * @param <T>    泛型
     * @return 转换后的对象
     */
    public <T> T getAttribute(String key, Class<T> tClass) {
        Object obj = getAttribute(key);
        return JsonUtil.jsonStrToObject(JsonUtil.objectToJsonStr(obj), tClass);
    }

    /**
     * 刷新token存储
     */
    public void flushTokenStorage() {
        boolean result = SecurityFactory.getSecurityRepository.get().saveToken(this);
        if (!result) {
            throw new SecurityBusinessException(ErrorCodeConstant.CODE_SAVE_TOKEN_FAILED, "保存token认证数据失败");
        }
    }
}
